package com.dly.blog.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dly.blog.domain.GptSessionContent;
import com.dly.blog.domain.UserGptSession;
import com.dly.blog.domain.dto.MessageContentDto;
import com.dly.blog.domain.ro.ChatGptRO;
import com.dly.blog.domain.vo.GptSessionVO;
import com.dly.blog.mapper.GptSessionMapper;
import com.dly.blog.service.GptSessionContentService;
import com.dly.blog.service.GptSessionService;
import com.dly.blog.utile.SecurityUtils;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

@Service
@AllArgsConstructor
public class GptSessionServiceImpl extends ServiceImpl<GptSessionMapper, UserGptSession> implements GptSessionService{

    private final GptSessionContentService gptSessionContentService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createGptSession(ChatGptRO chatGptRO) {
        List<GptSessionContent> contents = chatGptRO.cover();
        UserGptSession userGptSession = new UserGptSession();
        userGptSession.setTitle(contents.get(0).getContent());
        this.save(userGptSession);
        contents.forEach(gptSessionContent -> gptSessionContent.setSessionId(userGptSession.getId()));
        gptSessionContentService.saveBatch(contents);
        return userGptSession.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createGptSession(String userId, ChatGptRO chatGptRO) {
        List<GptSessionContent> contents = chatGptRO.cover();
        UserGptSession userGptSession = new UserGptSession();
        userGptSession.setTitle(contents.get(0).getContent());
        userGptSession.setCreateUser(userId);
        this.save(userGptSession);
        contents.forEach(gptSessionContent -> {
            gptSessionContent.setSessionId(userGptSession.getId());
            gptSessionContent.setCreateUser(userId);
        });
        gptSessionContentService.saveBatch(contents);
        return userGptSession.getId();
    }

    @Override
    public List<GptSessionVO> getList() {
        LambdaQueryWrapper<UserGptSession> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .select(UserGptSession::getId, UserGptSession::getTitle, UserGptSession::getCreateTime)
                .eq(UserGptSession::getCreateUser, SecurityUtils.getUserId())
                .orderByDesc(true, List.of(UserGptSession::getCreateTime));
        List<UserGptSession> list = this.list(queryWrapper);
        return list.stream().map(userGptSession ->
                GptSessionVO.builder()
                        .sessionId(userGptSession.getId())
                        .title(userGptSession.getTitle())
                        .createTime(userGptSession.getCreateTime()).build()
        ).toList();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String sessionId) {
        this.removeById(sessionId);
        gptSessionContentService.remove(new LambdaQueryWrapper<GptSessionContent>()
                .eq(GptSessionContent::getSessionId, sessionId));
    }

    @Override
    public List<MessageContentDto> getContent(String sessionId) {
        return gptSessionContentService.list(new LambdaQueryWrapper<GptSessionContent>()
                .select(GptSessionContent::getSessionId, GptSessionContent::getContent, GptSessionContent::getRole, GptSessionContent::getCreateTime)
                .eq(GptSessionContent::getSessionId, sessionId)
                .orderByAsc(GptSessionContent::getCreateTime)
                .orderByDesc(GptSessionContent::getRole)
        ).stream().map(gptSessionContent -> {
            MessageContentDto messageContentDto = new MessageContentDto();
            messageContentDto.setContent(gptSessionContent.getContent());
            messageContentDto.setRole(gptSessionContent.getRole());
            return messageContentDto;
        }).toList();
    }

    @Override
    public Integer getHistoryNum() {
        LambdaQueryWrapper<UserGptSession> queryChainWrapper = new LambdaQueryWrapper<UserGptSession>().eq(UserGptSession::getCreateUser, SecurityUtils.getUserId());
        return (int)this.count(queryChainWrapper);
    }

}
